package v1

import org.lwjgl.opengl.GL15C.*
import org.lwjgl.opengl.GL30C
import org.lwjgl.system.MemoryUtil

class Mesh(
    positions: FloatArray,
    normals:FloatArray,
    indices: IntArray,
) {
    val vaoId:Int
    var posVBO: Int
    var normalVBO: Int
    var indicesVBO:Int
    var vertexCount: Int = indices.size

    init {
        // vao
        vaoId = GL30C.glGenVertexArrays()
        GL30C.glBindVertexArray(vaoId)

        // position vbo
        val vertexBuffer = MemoryUtil.memAllocFloat(positions.size)
        vertexBuffer.put(positions).flip()
        posVBO = GL30C.glGenBuffers()
        GL30C.glBindBuffer(GL30C.GL_ARRAY_BUFFER, posVBO)
        GL30C.glBufferData(GL30C.GL_ARRAY_BUFFER, vertexBuffer, GL30C.GL_STATIC_DRAW)
        GL30C.glEnableVertexAttribArray(0)
        GL30C.glVertexAttribPointer(0, 3, GL30C.GL_FLOAT, false, 0, 0)
        MemoryUtil.memFree(vertexBuffer)

        // normal vbo
        val normalBuffer = MemoryUtil.memAllocFloat(normals.size)
        normalBuffer.put(normals).flip()
        normalVBO = GL30C.glGenBuffers()
        GL30C.glBindBuffer(GL30C.GL_ARRAY_BUFFER, normalVBO)
        GL30C.glBufferData(GL30C.GL_ARRAY_BUFFER, normalBuffer, GL30C.GL_STATIC_DRAW)
        GL30C.glEnableVertexAttribArray(1)
        GL30C.glVertexAttribPointer(1, 3, GL30C.GL_FLOAT, false, 0, 0)
        MemoryUtil.memFree(normalBuffer)

        // ibo
        val indicesBuffer = MemoryUtil.memAllocInt(indices.size)
        indicesBuffer.put(indices).flip()
        indicesVBO = GL30C.glGenBuffers()
        glBindBuffer(GL30C.GL_ELEMENT_ARRAY_BUFFER, indicesVBO)
        glBufferData(GL30C.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL30C.GL_STATIC_DRAW)
        MemoryUtil.memFree(indicesBuffer)

        // unbind
        GL30C.glBindBuffer(GL30C.GL_ARRAY_BUFFER, 0)
        GL30C.glBindVertexArray(0)
    }

    fun cleanup() {
        GL30C.glDisableVertexAttribArray(0)
        GL30C.glDisableVertexAttribArray(1)

        // delete vbo
        glBindBuffer(GL_ARRAY_BUFFER, 0)
        glDeleteBuffers(posVBO)
        glDeleteBuffers(normalVBO)
        glDeleteBuffers(indicesVBO)

        // delete vao
        GL30C.glBindVertexArray(0)
        GL30C.glDeleteVertexArrays(vaoId)
    }

    fun render() {
        GL30C.glBindVertexArray(vaoId)
        GL30C.glDrawElements(GL30C.GL_TRIANGLES, vertexCount, GL30C.GL_UNSIGNED_INT, 0)
        GL30C.glBindVertexArray(0)
    }
}